package com.sugon.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.sugon.entity.DeviceInfoEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.List;

@Slf4j
public class QRcodePOI {
    /**
     * 颜色
     */
    private static final int QRCOLOR = 0xFF000000;
    /**
     * 背景颜色
     */
    private static final int BGWHITE = 0xFFFFFFFF;

    /**
     * export
     *
     * @param response
     * @param list
     */
    public void export(HttpServletResponse response, List<DeviceInfoEntity> list) {
        String name = "二维码信息";
        //创建标题
        String title = "主要生产设备二维码信息";
        //创建doc文档
        XWPFDocument doc = new XWPFDocument();
        //创建标题
        XWPFParagraph titleParagraph = doc.createParagraph();
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);//设置段落居中
        XWPFRun run = titleParagraph.createRun();
        run.setText(title);
        run.setBold(true); //加粗
        run.setFontSize(15);
        XWPFTable table = doc.createTable(1, 3);
        CTTbl ttbl = table.getCTTbl();
        CTTblGrid tblGrid = ttbl.addNewTblGrid();
        tblGrid.addNewGridCol();
        setTableHeight(table, 100);
        setTableWidthAndHAlign(table);
        //表头
        setHeaderCellText(table, table.getRow(0).getCell(0), "序号");
        setHeaderCellText(table, table.getRow(0).getCell(1), "二维码");
        setHeaderCellText3(table, table.getRow(0).getCell(2), "设备信息");
        try {
            for (int i = 0; i < list.size(); i++) {
                DeviceInfoEntity dev = list.get(i);
                insertTable(doc, i, dev, table);
            }
        } catch (Exception r) {
            // 记录日志即可
            log.error(r.getMessage(), r);
        }
        OutputStream os;
        try {
            response.reset();
            response.setContentType("application/vnd.ms-word;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(name + ".doc", "UTF-8"))));
            os = response.getOutputStream();
            doc.write(os);
            os.flush();
            os.close();
        } catch (IOException e) {
            // 记录日志即可
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 设置表格行高
     *
     * @param infoTable
     * @param heigth    高度
     * @param
     * @Author sugon 2018年12月16日
     */
    public void setTableHeight(XWPFTable infoTable, int heigth) {
        List<XWPFTableRow> rows = infoTable.getRows();
        for (XWPFTableRow row : rows) {
            CTTrPr trPr = row.getCtRow().addNewTrPr();
            CTHeight ht = trPr.addNewTrHeight();
            ht.setVal(BigInteger.valueOf(heigth));
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell tableCell : cells) {
                CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();
                cttcpr.addNewVAlign().setVal(STVerticalJc.CENTER);
            }
        }
    }

    /**
     * @Description: 设置表格总宽度与水平对齐方式
     */
    public void setTableWidthAndHAlign(XWPFTable table) {
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        // 表格宽度
//        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        CTJc cTJc = tblPr.addNewJc();
        cTJc.setVal(STJc.CENTER);
        // 设置宽度
        CTTblWidth comTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setType(STTblWidth.DXA);
//        comTableWidth.setW(BigInteger.valueOf(7000));

    }

    /**
     * 设置表头内容
     *
     * @param cell
     * @param text
     * @param
     */
    private void setHeaderCellText(XWPFTable table, XWPFTableCell cell, String text) {
        CTTc cttc = cell.getCTTc();
        setTableWidthAndHAlign(table);
        XWPFParagraph paragraph = cell.getParagraphs().get(0);
        paragraph.setAlignment(ParagraphAlignment.CENTER); //设置表头单元格居中
        XWPFRun run = paragraph.createRun();
//        run.setFontFamily("仿宋_GB2312");
        run.setFontSize(12); //设置表头单元格字号
        run.setBold(true); //设置表头单元格加粗
        run.setText(text);
    }

    /**
     * setHeaderCellText3
     *
     * @param table
     * @param cell
     * @param text
     */
    private void setHeaderCellText3(XWPFTable table, XWPFTableCell cell, String text) {
        setTableWidthAndHAlign(table);
        XWPFParagraph paragraph = cell.getParagraphs().get(0);
        paragraph.setAlignment(ParagraphAlignment.CENTER); //设置表头单元格居中
        XWPFRun run = paragraph.createRun();
        CTTblWidth comTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setW(BigInteger.valueOf(5500));
//        run.setFontFamily("仿宋_GB2312");
        run.setFontSize(12); //设置表头单元格字号
        run.setBold(true); //设置表头单元格加粗
        run.setText(text);
    }

    /**
     * generateQRCodeImage
     *
     * @param devProductCode
     * @param devProceCode
     * @param code
     * @return
     */
    private BufferedImage generateQRCodeImage(String devProductCode, String devProceCode, String code) {
        MultiFormatWriter multiFormatWriter;
        BitMatrix bm;
        BufferedImage image = null;
        int width = 350;
        int height = 350;
        try {
            multiFormatWriter = new MultiFormatWriter();
            bm = multiFormatWriter.encode(code, BarcodeFormat.QR_CODE, width, height);
            int w = bm.getWidth();
            int h = bm.getHeight();
            image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
                }
            }

            //x开始的位置：（图片宽度-字体大小*字的个数）/2
            Font font = new java.awt.Font(null, java.awt.Font.BOLD, 25);
            java.awt.FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(font);

            // 设置底部字体
            String bottomText = devProductCode + "/" + devProceCode;
            int startX = (width - fm.stringWidth(bottomText)) / 2;

            // 底部写入字体
            Graphics g = image.createGraphics();
            g.setFont(font);
            g.setColor(Color.GRAY);
            g.drawImage(image, 0, 0, 350, 350, null);
            g.drawString(bottomText, startX, 330);
            g.dispose();
            // 顶部写入字体
            startX = (width - fm.stringWidth(code)) / 2;
            g = image.createGraphics();
            g.setFont(font);
            g.setColor(Color.GRAY);
            g.drawImage(image, 0, 0, 350, 350, null);
            g.drawString(code, startX, 35);
            g.dispose();
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return image;
    }

    /**
     * img转输出流
     *
     * @param image
     * @return
     * @throws IOException
     */
    public InputStream tran(BufferedImage image) throws IOException {
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
        ImageIO.write(image, "jpg", imOut);
        InputStream inputStream = new ByteArrayInputStream(bs.toByteArray());
        return inputStream;
    }

    /**
     * 插入数据
     *
     * @param doc
     * @param i
     * @param entity
     * @param table
     * @throws IOException
     * @throws InvalidFormatException
     */
    private void insertTable(XWPFDocument doc, int i, DeviceInfoEntity entity, XWPFTable table) throws IOException, InvalidFormatException {
        XWPFTableRow row = table.insertNewTableRow(i + 1);//添加一个新行
        row.createCell();
        row.createCell();
        row.createCell();
        List<XWPFTableCell> cells = table.getRow(i + 1).getTableCells();
        for (int l = 0; l < cells.size(); l++) {
            XWPFTableCell cell02 = cells.get(l);
            if (l == 0) {
                cell02.setText(i + 1 + ".");
            } else if (l == 2) {
                cell02.setText("设备编码: ");
                addBreaks(cell02);
                cell02.setText(entity.getDevCode() + ";  ");
                addBreaks(cell02);
                cell02.setText("设备名称: ");
                addBreaks(cell02);
                cell02.setText(entity.getDevName() + ";  ");
                addBreaks(cell02);
                cell02.setText("产线名称: ");
                addBreaks(cell02);
                cell02.setText(entity.getDevProductName() + ";  ");
                addBreaks(cell02);
                cell02.setText("工序名称: ");
                addBreaks(cell02);
                cell02.setText(entity.getDevProceName() + ";  ");
            }
        }
        XWPFTableRow rowTest = table.getRow(i + 1);
        XWPFTableCell imageCell = rowTest.getCell(1);
        List<XWPFParagraph> paragraphs = imageCell.getParagraphs();
        XWPFParagraph newPara = paragraphs.get(0);
        XWPFRun imageCellRun = newPara.createRun();
        imageCellRun.addBreak();
        BufferedImage image = generateQRCodeImage(entity.getDevProductCode(), entity.getDevProceNo(), entity.getDevCode());
        InputStream inputStream = tran(image);
        //设置段落f行
        CTInline ctinline = imageCellRun.getCTR().addNewDrawing().addNewInline();
        //添加图片数据
        String id = doc.addPictureData(inputStream, XWPFDocument.PICTURE_TYPE_PNG);
        int id2 = doc.getAllPackagePictures().size() + 1;
        //添加图片
        CustomXWPFDocument.createPic(id, id2, 150, 150, ctinline);
    }

    /**
     * addBreaks
     *
     * @param cell02
     */
    public void addBreaks(XWPFTableCell cell02) {
        List<XWPFParagraph> lists = cell02.getParagraphs();
        XWPFParagraph paragraph = lists.get(0);
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun run = paragraph.createRun();
        run.addBreak();
    }

}
